package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.exception.CustomException;
import com.heima.feign.article.IArticleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.GreenScanService;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
@SuppressWarnings("all")
public class WmNewsAutoScanServiceImpl2 {
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private GreenScanService greenScanService;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private WmChannelMapper wmChannelMapper;
    @Autowired
    private IArticleClient iArticleClient;

    /**
     * 自媒体文章审核
     *
     * @param id
     */
    public void autoScanWmNews(Integer id) {
        //1、先通过id获取自媒体发布的文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        //1.1、判断文章是否有效
        if (wmNews == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);//数据不存在
        }
        // 发布的文章才需要审核
        if (wmNews.getStatus() == WmNews.Status.SUBMIT.getCode()) {
            //2、提取文章中的文本以及图片信息 用map集合来装
            Map<String, Object> map = extractTextAndImage(wmNews);
            //3、审核文本
            boolean isTextScan = scanText((String) map.get("text"), wmNews);
            if (!isTextScan) return;//违规直接结束方法
            //4、审核图片
            boolean isImageScan = scanImage((List<String>) map.get("image"), wmNews);
            if (!isImageScan) return;//违规直接结束方法
            //5、到这说明审核通过，远程调用文章微服务保存文章
            ResponseResult responseResult = saveOrUpdate(wmNews);
            //6、判断远程调用是否成功，成功返回文章id，存入自媒体文章表
            if (responseResult.getCode() == 200) {
                //代表成功 修改文章表 放入文章id
                wmNews.setArticleId((Long) responseResult.getData());
                updateNews(wmNews, WmNews.Status.PUBLISHED.getCode(), "审核成功");
            }
        }
    }

    /**
     * 远程调用article微服务
     *
     * @param wmNews
     * @return
     */
    private ResponseResult saveOrUpdate(WmNews wmNews) {
        //1、准备一个dto封装数据
        ArticleDto dto = new ArticleDto();
        //2、拷贝数据（大部分）
        BeanUtils.copyProperties(wmNews, dto);
        //3、不能拷贝的数据，手动处理
        //3.1、id
        if (wmNews.getArticleId() != null) {
            //说明是修改文章，要把文章id带过去
            dto.setId(wmNews.getArticleId());
        }
        //3.2、作者id
        dto.setAuthorId(wmNews.getUserId().longValue());
        //3.3、作者名称
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        dto.setAuthorName(wmUser.getName());
        //3.4、频道名称
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());
        //3.5、文章布局
        dto.setLayout(wmNews.getType());
        //4、远程调用 并返回结果
        return iArticleClient.savaOrUpdate(dto);
    }

    /**
     * 审核图片
     *
     * @param imageList
     * @param wmNews
     * @return
     */
    private boolean scanImage(List<String> imageList, WmNews wmNews) {
        //0、信号位
        boolean flag = true;
        //1、为空直接返回true
        if (imageList == null || imageList.size() == 0) {
            return flag;
        }
        //2、图片去重
        imageList = imageList.stream().distinct().collect(Collectors.toList());
        //3、调用百度云接口审核图片 遍历一张一张审核
        for (String image : imageList) {
            try {
                Map map = greenScanService.scanImage(image);
                if (map != null) {//非空校验
                    if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_ILLEGAL) {
                        //违规
                        flag = false;
                        updateNews(wmNews, WmNews.Status.FAIL.getCode(), "图片内容违规");
                        break; //跳出循环
                    }
                    if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_SUSPECTED) {
                        //疑似
                        flag = false;
                        updateNews(wmNews, WmNews.Status.FAIL.getCode(), "图片内容疑似违规，需人工审核");
                        break; //跳出循环
                    }
                }

            } catch (Exception e) {
                flag = false; //异常则审核失败
                e.printStackTrace();
            }

        }
        //4、返回信号位
        return flag;
    }

    /**
     * 审核文本
     *
     * @param text
     * @return
     */
    private boolean scanText(String text, WmNews wmNews) {
        //0、信号位
        boolean flag = true;
        //1、为空不审核，直接返回true
        if (text == null) {
            return flag;
        }
        //2、调用百度云接口审核文本
        try {
            Map map = greenScanService.scanText(text);
            // 2.1、非空校验
            if (map != null) {
                if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_ILLEGAL) {
                    //违规
                    flag = false;
                    updateNews(wmNews, WmNews.Status.FAIL.getCode(), "文章文本内容涉嫌违规");
                }
                if ((int) map.get("conclusionType") == WemediaConstants.BAIDU_SCAN_SUSPECTED) {
                    //疑似
                    flag = false;
                    updateNews(wmNews, WmNews.Status.ADMIN_AUTH.getCode(), "文章内容疑似违规");
                }
            }
        } catch (Exception e) {
            //有异常也表示审核失败
            flag = false;
            e.printStackTrace();
        }
        //返回信号位
        return flag;
    }

    /**
     * 修改文章
     *
     * @param wmNews
     * @param code
     * @param reason
     */
    private void updateNews(WmNews wmNews, short code, String reason) {
        wmNews.setReason(reason);
        wmNews.setStatus(code);
        wmNewsMapper.updateById(wmNews);
    }

    /**
     * 提取文章中的文本以及图片内容
     *
     * @param wmNews
     * @return
     */
    private Map<String, Object> extractTextAndImage(WmNews wmNews) {
        //1、创建容器储存文本内容 标题以及标签
        StringBuilder stringBuilder = new StringBuilder(wmNews.getTitle());
        stringBuilder.append(wmNews.getLabels());
        //2、创建容器储存图片内容
        List<String> imageList = new ArrayList<>();
        //3、获取文章内容
        if (StringUtils.isNotBlank(wmNews.getContent())) {
            //3.1、解析文章内容（json转数组）
            JSONArray jsonArray = JSON.parseArray(wmNews.getContent());
            //3.2、遍历数组
            for (Object json : jsonArray) {
                //3.3、转为jsonobject对象处理
                JSONObject jsonObject = JSON.parseObject(json.toString());
                //3.4、判断  文本还是图片
                if (jsonObject.get("type").equals("text")) {
                    //文本，添加到容器
                    stringBuilder.append(jsonObject.get("value").toString());
                }
                if (jsonObject.get("type").equals("image")) {
                    //图像，添加到容器
                    imageList.add(jsonObject.get("value").toString());
                }
            }
        }
        //4、获取文章封面图片信息 先分割再批量添加
        imageList.addAll(Arrays.asList(wmNews.getImages().split(",")));
        //5、封装到map集合返回
        HashMap<String, Object> map = new HashMap<>();
        map.put("text", stringBuilder.toString());
        map.put("image", imageList);
        return map;
    }
}
